﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Routing;
using Kugar.Core.BaseStruct;
using Kugar.Core.Configuration;
using Kugar.Tool.DataSync.ClientPlugin;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Kugar.Tool.DataSync.Client.BLL
{
    public class PluginManager
    {
        private CompositionContainer _mainContainer = null;
        private List<IImporterPlugin> _importers = null;
        private List<IExporterPlugin> _exporter = null;
        private string _pluginPath = "";
        private AggregateCatalog _aggregateCatalog = new AggregateCatalog();
        private HttpTransfer _transfer=null;

        public PluginManager(string pluginPath)
        {
            _pluginPath = pluginPath;
            _mainContainer=new CompositionContainer(_aggregateCatalog);

            var host = CustomConfigManager.Default.AppSettings.GetValueByName("ExportUrl");
            var appID = CustomConfigManager.Default.AppSettings.GetValueByName("AppID");
            var appSecret = CustomConfigManager.Default.AppSettings.GetValueByName("AppSecret");

            _transfer=new HttpTransfer(host,appID,appSecret);
        }

        public void Initialize(HttpConfiguration config)
        {
            _aggregateCatalog.Catalogs.Add(new DirectoryCatalog(_pluginPath));
            _aggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(PluginManager).Assembly));

            var starters = _mainContainer.GetExportedValues<ISyncPluginStarter>().ToList();

            foreach (var starter in starters)
            {
                starter.Start(config);
            }

            var exporters = _mainContainer.GetExportedValues<IExporterPlugin>();

            foreach (var exporter in exporters)
            {
                exporter.Initialize(SendData);
            }
        }

        /// <summary>
        /// 导出发送数据
        /// </summary>
        /// <param name="dataTypeName"></param>
        /// <param name="data"></param>
        private void SendData(string dataTypeName, JObject data)
        {
            _transfer.Send(dataTypeName, data);
        }

        public CompositionContainer Container => _mainContainer;

        public ResultReturn TriggerImport(string dataType, JObject data)
        {
            var importers = _mainContainer.GetExportedValues<IImporterPlugin>().ToList();

            foreach (var plugin in importers)
            {
                if (plugin.CanHandleWith(dataType))
                {
                    try
                    {
                        return plugin.Import(dataType, data);
                    }
                    catch (Exception ex)
                    {
                        //TODO:记录出错信息
                        continue;
                    }

                }
            }

            return new FailResultReturn("不存在能处理的插件");
        }

        public void Close()
        {
            var exporters = _mainContainer.GetExportedValues<IExporterPlugin>();

            foreach (var exporter in exporters)
            {
                exporter.Close();
            }

            var importers = _mainContainer.GetExportedValues<IImporterPlugin>();

            foreach (var importer in importers)
            {
                importer.Close();
            }
        }
    }

    public class HttpTransfer : ITransfer
    {
        private string _url = "";
        private string _appID = "";
        private string _appSecret = "";

        public HttpTransfer(string url,string appID,string appSecret)
        {
            _url = url;
            _appID = appID;
            _appSecret = appSecret;
        }

        public ResultReturn Send(string dataTypeName, JObject data)
        {
            using (var client=new WebClient())
            {
                client.BaseAddress = _url;
                try
                {
                    var u =
                        $"{_url}?appid={_appID}&AppSecret={_appSecret}&DataType={WebUtility.UrlEncode(dataTypeName)}";

                    var retJson=client.UploadString(u,"Post",data.ToString(Formatting.None));

                    return JsonConvert.DeserializeObject<ResultReturn>(retJson);
                }
                catch (Exception ex)
                {
                    return new FailResultReturn(ex);
                }
                
            }
        }
    }
}
